﻿/* 
 
This file is part of Ingo Karstein's Custom SharePoint 2010 Ribbon project

**Do not remove this comment**

Please see the project homepage at CodePlex:
  http://spcustomribbondemo.codeplex.com

Please see my blog:
  http://ikarstein.wordpress.com

Licence: GPLv2
    Ingo Karstein's SharePoint 2010 Custom Ribbon Demo
    Copyright (C) 2011  Ingo Karstein, ikarstein@hotmail.com

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Xml;
using Microsoft.SharePoint.Workflow;
using System.Web.UI;
using System.Web;

namespace ik.SharePoint2010.SPCustomTabRibbonDemo.RibbonByDelegateControl
{
    class RibbonDelegateControl : WebControl, IPostBackEventHandler
    {
        /*
            <CustomAction Id="" RegistrationType="ContentType" RegistrationId="document-set"
                javascript:__doPostBack('postbackid','');
        */

        #region Tab Template XML
        private string tab = @"
          <Tab Id=""ik.SharePoint2010.Ribbon.WorkflowTab"" Title=""Workflows"" Description=""Workflow Associations"" Sequence=""1000"">
            <Scaling Id=""ik.SharePoint2010.Ribbon.WorkflowTab.Scaling"">
              <MaxSize Id=""ik.SharePoint2010.Ribbon.WorkflowTab.Group1.MaxSize""
                       GroupId=""ik.SharePoint2010.Ribbon.WorkflowTab.Group1""
                       Size=""LargeLarge""/>
              <Scale Id=""ik.SharePoint2010.Ribbon.WorkflowTab.Group1.Scaling.WorkflowTabScaling""
                     GroupId=""ik.SharePoint2010.Ribbon.WorkflowTab.Group1""
                     Size=""Popup""/>
            </Scaling>
            <Groups Id=""ik.SharePoint2010.Ribbon.WorkflowTab.Groups"">
              <Group Id=""ik.SharePoint2010.Ribbon.WorkflowTab.Group1""
                     Description=""All associated workflows""
                     Title=""Workflows""
                     Sequence=""10""
                     Template=""copyof.Ribbon.Templates.Flexible2"">
                <Controls Id=""ik.SharePoint2010.Ribbon.WorkflowTab.Group1.Controls"">
$$$$
                </Controls>
              </Group>
            </Groups>
          </Tab>

";
        #endregion

        #region Button Template
        private string buttonTemplate = @"
                  <Button Id=""ik.SharePoint2010.Ribbon.WorkflowTab.Group1.Button$<id>$""
                          Command=""ik.SharePoint2010.Command.WorkflowButton$<id>$""
                          Description=""$<descr>$""
                          Sequence=""$<seq>$""
                          LabelText=""$<label>$""
                          Image16by16=""$<siteurl>$/_layouts/$<lcid>$/images/formatmap16x16.png""
                          Image32by32=""$<siteurl>$/_layouts/$<lcid>$/images/formatmap32x32.png""
                          Image32by32Top=""-192"" 
                          Image32by32Left=""-416""  
                          Image16by16Top=""-48"" 
                          Image16by16Left=""-208"" 
                          TemplateAlias=""o1""/>
$$$$  
";
        #endregion

        #region Group Template XML
        private string tabTempl = @"
<GroupTemplate Id=""copyof.Ribbon.Templates.Flexible2"">
        <Layout Title=""LargeLarge"">
          <OverflowSection Type=""OneRow"" TemplateAlias=""o1"" DisplayMode=""Large""/>
          <OverflowSection Type=""OneRow"" TemplateAlias=""o2"" DisplayMode=""Large""/>
        </Layout>
        <Layout Title=""LargeMedium"">
          <OverflowSection Type=""OneRow"" TemplateAlias=""o1"" DisplayMode=""Large""/>
          <OverflowSection Type=""ThreeRow"" TemplateAlias=""o2"" DisplayMode=""Medium""/>
        </Layout>
        <Layout Title=""LargeSmall"">
          <OverflowSection Type=""OneRow"" TemplateAlias=""o1"" DisplayMode=""Large""/>
          <OverflowSection Type=""ThreeRow"" TemplateAlias=""o2"" DisplayMode=""Small""/>
        </Layout>
        <Layout Title=""MediumLarge"">
          <OverflowSection Type=""ThreeRow"" TemplateAlias=""o1"" DisplayMode=""Medium""/>
          <OverflowSection Type=""OneRow"" TemplateAlias=""o2"" DisplayMode=""Large""/>
        </Layout>
        <Layout Title=""MediumMedium"">
          <OverflowSection Type=""ThreeRow"" TemplateAlias=""o1"" DisplayMode=""Medium""/>
          <OverflowSection Type=""ThreeRow"" TemplateAlias=""o2"" DisplayMode=""Medium""/>
        </Layout>
        <Layout Title=""MediumSmall"">
          <OverflowSection Type=""ThreeRow"" TemplateAlias=""o1"" DisplayMode=""Medium""/>
          <OverflowSection Type=""ThreeRow"" TemplateAlias=""o2"" DisplayMode=""Small""/>
        </Layout>
        <Layout Title=""SmallLarge"">
          <OverflowSection Type=""ThreeRow"" TemplateAlias=""o1"" DisplayMode=""Small""/>
          <OverflowSection Type=""OneRow"" TemplateAlias=""o2"" DisplayMode=""Large""/>
        </Layout>
        <Layout Title=""SmallMedium"">
          <OverflowSection Type=""ThreeRow"" TemplateAlias=""o1"" DisplayMode=""Small""/>
          <OverflowSection Type=""ThreeRow"" TemplateAlias=""o2"" DisplayMode=""Medium""/>
        </Layout>
        <Layout Title=""SmallSmall"">
          <OverflowSection Type=""ThreeRow"" TemplateAlias=""o1"" DisplayMode=""Small""/>
          <OverflowSection Type=""ThreeRow"" TemplateAlias=""o2"" DisplayMode=""Small""/>
        </Layout>
        <Layout Title=""Popup"" LayoutTitle=""LargeMedium"" />
      </GroupTemplate>
";
        #endregion

        #region JavaScript
        private string jScript = @"
function ULS_SP() {
    if (ULS_SP.caller) {
        ULS_SP.caller.ULSTeamName = ""Windows SharePoint Services 4"";
        ULS_SP.caller.ULSFileName = ""ikWorkflowRibbon.UI.js"";
    }
}

Type.registerNamespace('ikWorkflowRibbon.UI');

//  Page Component
ikWorkflowRibbon.UI.PageComponent = function () {
    ULS_SP();
    ikWorkflowRibbon.UI.PageComponent.initializeBase(this);
}
ikWorkflowRibbon.UI.PageComponent.initialize = function () {
    ULS_SP();
    ExecuteOrDelayUntilScriptLoaded(Function.createDelegate(null, ikWorkflowRibbon.UI.PageComponent.initializePageComponent), 'SP.Ribbon.js');
}
ikWorkflowRibbon.UI.PageComponent.initializePageComponent = function () {
    ULS_SP();
    var ribbonPageManager = SP.Ribbon.PageManager.get_instance();
    if (null !== ribbonPageManager) {
        ribbonPageManager.addPageComponent(ikWorkflowRibbon.UI.PageComponent.instance);
        ribbonPageManager.get_focusManager().requestFocusForComponent(ikWorkflowRibbon.UI.PageComponent.instance);
    }
}
ikWorkflowRibbon.UI.PageComponent.refreshRibbonStatus = function () {
    SP.Ribbon.PageManager.get_instance().get_commandDispatcher().executeCommand(Commands.CommandIds.ApplicationStateChanged, null);
}
ikWorkflowRibbon.UI.PageComponent.prototype = {
    getFocusedCommands: function () {
        ULS_SP();
        return [];
    },
    getGlobalCommands: function () {
        ULS_SP();
        return getGlobalCommands();
    },
    isFocusable: function () {
        ULS_SP();
        return true;
    },
    receiveFocus: function () {
        ULS_SP();
        return true;
    },
    yieldFocus: function () {
        ULS_SP();
        return true;
    },
    canHandleCommand: function (commandId) {
        ULS_SP();
        return commandEnabled(commandId);
    },
    handleCommand: function (commandId, properties, sequence) {
        ULS_SP();
        return handleCommand(commandId, properties, sequence);
    }
}

var ikWorkflowRibbonActiveInterval = null;

function ikWorkflowRibbonActiveRibbonTab() {
    try {
        window.clearInterval(ikWorkflowRibbonActiveInterval);

        if (typeof (_ribbonStartInit) == ""function"") {
            //_ribbonStartInit('ik.SharePoint2010.Ribbon.WorkflowTab', false, null);
        }

        if (true && typeof (_ribbonReadyForInit) == 'function' && !_ribbonReadyForInit()) {
            ikWorkflowRibbonActiveInterval = window.setInterval(""ikWorkflowRibbonActiveRibbonTab()"", 100);
        }
    } catch (e2) {
    };
};

function ikWorkflowRibbonInit() {
    ikWorkflowRibbon.UI.PageComponent.registerClass('ikWorkflowRibbon.UI.PageComponent', CUI.Page.PageComponent);
    ikWorkflowRibbon.UI.PageComponent.instance = new ikWorkflowRibbon.UI.PageComponent();
    ikWorkflowRibbon.UI.PageComponent.initialize();

    ExecuteOrDelayUntilScriptLoaded(ikWorkflowRibbonActiveRibbonTab, 'ikWorkflowRibbon.UI.js');
}

NotifyScriptLoadedAndExecuteWaitingJobs(""ikWorkflowRibbon.UI.js"");

ExecuteOrDelayUntilScriptLoaded(ikWorkflowRibbonInit, 'SP.Ribbon.js');

_spBodyOnLoadFunctionNames.push(""ikWorkflowRegisterEvents"");

function ikWorkflowRegisterEvents() {
    var ctx = GetCurrentCtx();
    var listview = document.getElementById(""onetidDoclibViewTbl0"");
    if( typeof(listview) != ""undefined"" ) {
        var rows = listview.getElementsByTagName(""TR"");
        var cbx = rows[0].getElementsByTagName('input');
        if (cbx != null) {      
            cbx[0].attachEvent('onclick', ikWorkflowSelectAllItems);
        }
    }

    for (var j = 0; j < rows.length; j++) {
        if (j != 0) {
            rows[j].attachEvent('onclick', ikWorkflowSelectItem);
            var cbx = rows[j].getElementsByTagName('input');
            if (typeof(chkbx) != ""undefined"" && cbx != null && cbx.length > 0) {
                cbx[0].attachEvent('onclick', ikWorkflowSelectItem);
            }
        }
    }
}  

function ikWorkflowSelectAllItems() {
    RefreshCommandUI();
}

function ikWorkflowSelectItem() {
    RefreshCommandUI();
}

function ikWorkflowRibbonSaveSelectedItems() {
    var items = GetSelectedItemsDict(ctx);
    var k;
    var joinedItems = """";
    for(k in items)
      joinedItems += k + "";"";
    return joinedItems;
}
";

        private string clickResponse = @"
_spBodyOnLoadFunctionNames.push(""ikWorkflowRibbonClickResponse"");

var ikwf_ctx;
var ikwf_web;

function ikWorkflowRibbonClickResponse() {
    ikwf_ctx = SP.ClientContext.get_current();
    ikwf_web = ikwf_ctx.get_web();
    ikwf_ctx.load(ikwf_web);
    ikwf_ctx.executeQueryAsync(Function.createDelegate(this, this.ikWorkflowRibbonClickResponseSuccess), Function.createDelegate(this, this.ikWorkflowRibbonClickResponseFailure));
}

function ikWorkflowRibbonClickResponseSuccess() {
    var weburl = ikwf_web.get_serverRelativeUrl();
    var pageurl = weburl + '/_layouts/ik.SharePoint2010.SPCustomTabRibbonDemo/WorkflowAssociationResponse.aspx';
    var options = {
        url: pageurl + '?Message=$$1$$&Message2=$$3$$',
        tite: 'Workflow',
        allowMaximize: false,
        showClose: false,
        width: 300,
        height: 200,
        dialogReturnValueCallback: ikWorkflowRibbonDialogCallback
    };
    SP.UI.ModalDialog.showModalDialog(options);

}

function ikWorkflowRibbonDialogCallback(dialogResult, returnValue) {
    window.location.href = window.location.href;
}

function ikWorkflowRibbonClickResponseFailure() {
    alert('$$2$$');
}
";

        #endregion

        protected override void OnPreRender(EventArgs e)
        {
            try
            {
                if( SPContext.Current.List.WorkflowAssociations.Count > 0 )
                {
                    string finalTab = tab;

                    List<IRibbonCommand> commands = new List<IRibbonCommand>();
                    StringBuilder sb = new StringBuilder();

                    int i = 0;


                    foreach( SPWorkflowAssociation assoz in SPContext.Current.List.WorkflowAssociations.Cast<SPWorkflowAssociation>().OrderBy(name => name.Name) )
                    {
                        if( assoz.AllowManual )
                        {
                            i++;
                            string button = buttonTemplate;
                            button = button.Replace("$<id>$", i.ToString());
                            button = button.Replace("$<descr>$", assoz.Description);
                            button = button.Replace("$<label>$", assoz.Name);
                            button = button.Replace("$<seq>$", ( i * 10 ).ToString());
                            button = button.Replace("$<siteurl>$", SPContext.Current.Site.Url);
                            button = button.Replace("$<lcid>$", SPContext.Current.Web.Language.ToString());
                            finalTab = finalTab.Replace("$$$$", button);

                            commands.Add(new SPRibbonCommand("ik.SharePoint2010.Command.WorkflowButton" + i.ToString(), "ikSharePoint2010CommandWorkflowButton" + i.ToString() + "Clicked()", "ikSharePoint2010CommandWorkflowButton" + i.ToString() + "Enable()"));

                            sb.AppendLine("function ikSharePoint2010CommandWorkflowButton" + i.ToString() + "Clicked() {");
                            sb.AppendLine("  __doPostBack('" + this.UniqueID + "','" + assoz.Id.ToString() + ";'+ikWorkflowRibbonSaveSelectedItems());");
                            sb.AppendLine("};");
                            sb.AppendLine("");
                            sb.AppendLine("function ikSharePoint2010CommandWorkflowButton" + i.ToString() + "Enable() {");
                            sb.AppendLine("  var items = GetSelectedItemsDict(ctx);");
                            sb.AppendLine("  var cnt = CountSelectedItems(ctx);");
                            sb.AppendLine("  return cnt == 1;");
                            sb.AppendLine("};");
                        }
                    }

                    if( i == 0 )
                        return;

                    Literal l = new Literal();
                    l.Text = "<script language=\"javascript\">\r\n" + sb.ToString() + "\r\n</script>";
                    this.Controls.Add(l);

                    finalTab = finalTab.Replace("$$$$", "");

                    SPRibbon r = Microsoft.SharePoint.WebControls.SPRibbon.GetCurrent(this.Page);
                    XmlDocument rx = new XmlDocument();
                    rx.LoadXml(finalTab);
                    r.RegisterDataExtension(rx.FirstChild, "Ribbon.Tabs._children");
                    rx.LoadXml(tabTempl);
                    r.RegisterDataExtension(rx.FirstChild, "Ribbon.Templates._children");

                    SPRibbonScriptManager rsm = new SPRibbonScriptManager();

                    ScriptLink.RegisterScriptAfterUI(this.Page, "SP.Runtime.js", false, true);
                    ScriptLink.RegisterScriptAfterUI(this.Page, "SP.js", false, true);
                    ScriptLink.RegisterScriptAfterUI(this.Page, "CUI.js", false, true);
                    ScriptLink.RegisterScriptAfterUI(this.Page, "SP.Ribbon.js", false, true);
                    ScriptLink.RegisterScriptAfterUI(this.Page, "ik.SharePoint2010.SPCustomTabRibbonDemo/ikactions.js", false, true);
                    ScriptLink.RegisterScriptAfterUI(this.Page, "ik.SharePoint2010.SPCustomTabRibbonDemo/ikribbon.UI.js", false, true);

                    rsm.RegisterGetCommandsFunction(this.Page, "getGlobalCommands", commands);
                    rsm.RegisterCommandEnabledFunction(this.Page, "commandEnabled", commands);
                    rsm.RegisterHandleCommandFunction(this.Page, "handleCommand", commands);

                    this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "InitPageComponent", jScript.Replace("$$$$", this.ClientID + "_hdfld"), true);

                    r.MakeTabAvailable("ik.SharePoint2010.Ribbon.WorkflowTab");
                    //r.SetInitialTabId("ik.SharePoint2010.Ribbon.WorkflowTab", "");

                }
            }
            catch
            {
            }
            finally
            {

            }

            base.OnPreRender(e);
        }

        void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
        {
            int resultCode = 0;
            string resultMsg = "";
            string errorMsg = "";
            try
            {
                string[] param1 = eventArgument.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                string id = param1[1].Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)[1];
                string wfInternalName = param1[0];

                SPListItem item = SPContext.Current.List.GetItemById(int.Parse(id));

                SPWorkflowAssociation assoz = SPContext.Current.List.WorkflowAssociations[new Guid(wfInternalName)];
                if( assoz != null )
                {
                    SPContext.Current.Site.WorkflowManager.StartWorkflow(item, assoz, assoz.AssociationData);
                    resultCode = 1;
                    resultMsg = "Workflow successfully started!";
                };
                
            }
            catch(Exception ex)
            {
                resultMsg = "An error occured";
                errorMsg = ex.Message;
                resultCode = 2;
            }
            finally
            {
                this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "clickResponse", 
                        clickResponse.Replace("$$1$$", HttpUtility.UrlEncode(resultMsg)).Replace("$$2$$", resultMsg).Replace("$$3$$", HttpUtility.UrlEncode(errorMsg)), 
                        true);
            }
        }
    }
}
